#include "TcpConnection.h"
#include "HttpRequest.h"
#include <stdlib.h>
#include <stdio.h>
#include "Log.h"

int processRead(void* arg)
{
    struct TcpConnection* conn = (struct TcpConnection*)arg;
    //接收数据
    int count = bufferSocketRead(conn->readBuf, conn->channel->fd);
    Debug("接收到的http请求数据: %s", conn->readBuf->data + conn->readBuf->readPos);
    if(count > 0)
    {
        //接收到了http请求，解析http请求
        int socket = conn->channel->fd;
#ifdef MSG_SEND_AUTO//定义在头文件中
        //检测写事件，回复数据
        writeEventEnable(conn->channel, true);
        eventLoopAddTask(conn->evLoop, conn->channel, MODIFY);
#endif
        bool flag = parseHttpRequest(conn->request, conn->readBuf, conn->reponse, conn->writeBuf, socket);
        if(flag == false)
        {
            //解析失败 回复一个简单的html
            char* errMsg = "Http/1.1 400 Bad Request\r\n\r\n";
            bufferAppendString(conn->writeBuf, errMsg);
        }
    }

#ifndef MSG_SEND_AUTO//定义在头文件中
    //断开连接
    eventLoopAddTask(conn->evLoop, conn->channel, DELETE);
#endif
    return 0;
}

int processWrite(void* arg)
{
    Debug("开始发送数据....");
    struct TcpConnection* conn = (struct TcpConnection*)arg;
    //发送数据
    int count = bufferSendData(conn->writeBuf, conn->channel->fd);
    if(count > 0)
    {
        //判断数据是否被全部发送出去了
        if(bufferWriteAbleSize(conn->writeBuf) == 0)
        {
            //1.不再检测写事件 -- 修改channel中保存的事件
            writeEventEnable(conn->channel, false);
            //2.修改dispathcer检测的集合 -- 添加任务节点
            eventLoopAddTask(conn->evLoop, conn->channel, MODIFY);
            //3.删除这个节点
            eventLoopAddTask(conn->evLoop, conn->channel, DELETE);
        }
    }
    return 0;
}

//初始化
struct TcpConnection* TcpConnectionInit(int fd, struct EventLoop* evLoop)
{
    struct TcpConnection* conn = (struct TcpConnection*)malloc(sizeof(struct TcpConnection));
    conn->evLoop = evLoop;
    conn->readBuf = bufferInit(10240);
    conn->writeBuf = bufferInit(10240);
    //http
    conn->request = HttpRequestInit();
    conn->reponse = HttpResponseInit();
    sprintf(conn->name, "Connecction-%d", fd);
    conn->channel = channelInit(fd, ReadEvent, processRead, processWrite, TcpConnectionDestroy, conn);
    eventLoopAddTask(evLoop, conn->channel, ADD);
    Debug("和客户端建立连接, threadName: %s, threadID: %ld, connName: %s", 
    evLoop->threadName, evLoop->threadID, conn->name);
    return conn;
}

int TcpConnectionDestroy(void* arg)
{
    struct TcpConnection* conn = (struct TcpConnection*)arg;
    if(conn != NULL)
    {
        if(conn->readBuf && bufferReadAbleSize(conn->readBuf) == 0 &&
           conn->writeBuf && bufferWriteAbleSize(conn->writeBuf) == 0)
        {
            destroyChannel(conn->evLoop, conn->channel);
            bufferDestroy(conn->readBuf);
            bufferDestroy(conn->writeBuf);
            httpRequestDestroy(conn->request);
            httpResponseDestroy(conn->reponse);
            free(conn);
        }
    }
    Debug("连接断开, 释放资源, connName: %s", conn->name);
    return 0;
}
